//--------------------------------------------------------------------------------
// This file is a portion of the D2D1Renderer.  It is distributed
// under the MIT License, available in the root of this distribution and 
// at the following URL:
//
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright (c) Mirco Timmermann
//
//--------------------------------------------------------------------------------
#include "Graphics.h"

namespace D2 {

Graphics::Graphics() {

}

Graphics::~Graphics(void) {
	for(unsigned int i = 0; i < _commands.size(); i++) {
		delete _commands[i];
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////
//                          DRAW INTERFACE (CanvasRenderingContext2D)                        //
///////////////////////////////////////////////////////////////////////////////////////////////

void Graphics::save() {
	AddCommand(new Save());
}

void Graphics::restore() {
	AddCommand(new Restore());
}

void Graphics::clearRect(float x, float y, float w, float h) {
	AddCommand(new ClearRect(x, y, w, h));
}

void Graphics::fillRect(float x, float y, float w, float h) {
	AddCommand(new FillRect(x, y, w, h));
}

void Graphics::strokeRect(float x, float y, float w, float h) {
	AddCommand(new StrokeRect(x, y, w, h));
}

void Graphics::beginPath() {
	AddCommand(new BeginPath());
}

void Graphics::fill() {
	AddCommand(new Fill());
}

void Graphics::stroke() {
	AddCommand(new Stroke());
}

void Graphics::clip() {
	AddCommand(new Clip());
}

void Graphics::fillText(std::string text, float x, float y, float maxWidth) {
	AddCommand(new FillText(text, x, y, maxWidth));
}

void Graphics::strokeText(std::string text, float x, float y, float maxWidth) {
	AddCommand(new StrokeText(text, x, y, maxWidth));
}

///////////////////////////////////////////////////////////////////////////////////////////////
//                                     PATH INTERFACE                                        //
///////////////////////////////////////////////////////////////////////////////////////////////

// shared path API methods
void Graphics::closePath() {
	AddCommand(new ClosePath());
}

void Graphics::moveTo(float x, float y) {
	AddCommand(new MoveTo(x, y));
}

void Graphics::lineTo(float x, float y) {
	AddCommand(new LineTo(x, y));
}

void Graphics::quadraticCurveTo(float cpx, float cpy, float x, float y) {
	AddCommand(new QuadraticCurveTo(cpx, cpy, x, y));
}

void Graphics::bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y) {
	AddCommand(new BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y));
}

void Graphics::arcTo(float x1, float y1, float x2, float y2, float radius) {
	AddCommand(new ArcTo(x1, y1, x2, y2, radius));
}

void Graphics::rect(float x, float y, float w, float h) {
	AddCommand(new Rect(x, y, w, h));
}

void Graphics::arc(float x, float y, float radius, float startAngle, float endAngle, bool anticlockwise) {
	AddCommand(new Arc(x, y, radius, startAngle, endAngle, anticlockwise));
}

//

CanvasGradient Graphics::createLinearGradient(float x0, float y0, float x1, float y1) {
	CanvasGradient canvasGradient;

	//TODO:

	return canvasGradient;
}

CanvasGradient Graphics::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1) {
	CanvasGradient canvasGradient;

	//TODO:

	return canvasGradient;
}

///////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                           //
///////////////////////////////////////////////////////////////////////////////////////////////

void Graphics::setStrokeStyle(float r, float g, float b) {
	AddCommand(new SetStrokeStyle(r, g, b));
}

void Graphics::setFillStyle(float r, float g, float b) {
	AddCommand(new SetFillStyle(r, g, b));
}

void Graphics::setLineWidth(float width) {
	AddCommand(new SetLineWidth(width));
}

//////////////////////////////////////

void Graphics::AddCommand(Command* command) {
	_commands.push_back(command);
}

void Graphics::Execute(Direct2DContext* ctx) {
	for(unsigned int i = 0; i < _commands.size(); i++) {
		_commands[i]->execute(ctx); //_ctx);
	}
}

}